<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/*************************************************************************
 *                                                                       *
* HTML2TEXT Helper                                                      *
*                                                                       *
*************************************************************************
*                           											 *
* Manh Nguyen															 *
* Created: 02/11/2012													 *
* Last modified:                                             *
*                                                                       *
*************************************************************************/

/**
 *  Returns the text, converted from HTML.
 *
 *  @access public
 *  @return string
 */
function html2text($html)
{
	/**
	 *  List of preg* regular expression patterns to search for,
	 *  used in conjunction with $replace.
	 *
	 *  @var array $search
	 *  @access public
	 *  @see $replace
	 */
	$search = array(
    	        "/\r/",                                  // Non-legal carriage return
    	        "/[\n\t]+/",                             // Newlines and tabs
    	        '/[ ]{2,}/',                             // Runs of spaces, pre-handling
    	        '/<script[^>]*>.*?<\/script>/i',         // <script>s -- which strip_tags supposedly has problems with
    	        '/<style[^>]*>.*?<\/style>/i',           // <style>s -- which strip_tags supposedly has problems with
				//'/<!-- .* -->/',                         // Comments -- which strip_tags might have problem a with
    	        '/<h[123][^>]*>(.*?)<\/h[123]>/ie',      // H1 - H3
    	        '/<h[456][^>]*>(.*?)<\/h[456]>/ie',      // H4 - H6
    	        '/<p[^>]*>/i',                           // <P>
    	        '/<br[^>]*>/i',                          // <br>
    	        '/<b[^>]*>(.*?)<\/b>/ie',                // <b>
    	        '/<strong[^>]*>(.*?)<\/strong>/ie',      // <strong>
    	        '/<i[^>]*>(.*?)<\/i>/i',                 // <i>
    	        '/<em[^>]*>(.*?)<\/em>/i',               // <em>
    	        '/(<ul[^>]*>|<\/ul>)/i',                 // <ul> and </ul>
    	        '/(<ol[^>]*>|<\/ol>)/i',                 // <ol> and </ol>
    	        '/<li[^>]*>(.*?)<\/li>/i',               // <li> and </li>
    	        '/<li[^>]*>/i',                          // <li>
    	        '/<a [^>]*href="([^"]+)"[^>]*>(.*?)<\/a>/ie',
				// <a href="">
    	        '/<hr[^>]*>/i',                          // <hr>
    	        '/(<table[^>]*>|<\/table>)/i',           // <table> and </table>
    	        '/(<tr[^>]*>|<\/tr>)/i',                 // <tr> and </tr>
    	        '/<td[^>]*>(.*?)<\/td>/i',               // <td> and </td>
    	        '/<th[^>]*>(.*?)<\/th>/ie',              // <th> and </th>
    	        '/&(nbsp|#160);/i',                      // Non-breaking space
    	        '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i',
				// Double quotes
    	        '/&(apos|rsquo|lsquo|#8216|#8217);/i',   // Single quotes
    	        '/&gt;/i',                               // Greater-than
    	        '/&lt;/i',                               // Less-than
    	        '/&(amp|#38);/i',                        // Ampersand
    	        '/&(copy|#169);/i',                      // Copyright
    	        '/&(trade|#8482|#153);/i',               // Trademark
    	        '/&(reg|#174);/i',                       // Registered
    	        '/&(mdash|#151|#8212);/i',               // mdash
    	        '/&(ndash|minus|#8211|#8722);/i',        // ndash
    	        '/&(bull|#149|#8226);/i',                // Bullet
    	        '/&(pound|#163);/i',                     // Pound sign
    	        '/&(euro|#8364);/i',                     // Euro sign
    	        '/&[^&;]+;/i',                           // Unknown/unhandled entities
    	        '/[ ]{2,}/'                              // Runs of spaces, post-handling
	);
	 
	/**
	 *  List of pattern replacements corresponding to patterns searched.
	 *
	 *  @var array $replace
	 *  @access public
	 *  @see $search
	 */
	$replace = array(
    	        '',                                     // Non-legal carriage return
    	        ' ',                                    // Newlines and tabs
    	        ' ',                                    // Runs of spaces, pre-handling
    	        '',                                     // <script>s -- which strip_tags supposedly has problems with
    	        '',                                     // <style>s -- which strip_tags supposedly has problems with
				//'',                                     // Comments -- which strip_tags might have problem a with
    	        "\"\n\n\\1\n\n\"",          // H1 - H3
    	        "ucwords(\"\n\n\\1\n\n\")",             // H4 - H6
    	        "\n\n\t",                               // <P>
    	        "\n",                                   // <br>
    	        'strtoupper("\\1")',                    // <b>
    	        '"\\1"',                    			// <strong>
    	        '_\\1_',                                // <i>
    	        '_\\1_',                                // <em>
    	        "\n\n",                                 // <ul> and </ul>
    	        "\n\n",                                 // <ol> and </ol>
    	        "\t* \\1\n",                            // <li> and </li>
    	        "\n\t* ",                               // <li>
    	        '_build_link_list("\\1", "\\2")',
				// <a href="">
    	        "\n-------------------------\n",        // <hr>
    	        "\n\n",                                 // <table> and </table>
    	        "\n",                                   // <tr> and </tr>
    	        "\t\t\\1\n",                            // <td> and </td>
    	        "\"\t\t\\1\n\"",            // <th> and </th>
    	        ' ',                                    // Non-breaking space
    	        '"',                                    // Double quotes
    	        "'",                                    // Single quotes
    	        '>',
    	        '<',
    	        '&',
    	        '(c)',
    	        '(tm)',
    	        '(R)',
    	        '--',
    	        '-',
    	        '*',
    	        '�',
    	        'EUR',                                  // Euro sign. � ?
    	        '',                                     // Unknown/unhandled entities
    	        ' '                                     // Runs of spaces, post-handling
	);
	 
	$allowed_tags = '';
	 
	/**
	 *  Maximum width of the formatted text, in columns.
	 *
	 *  Set this value to 0 (or less) to ignore word wrapping
	 *  and not constrain text to a fixed-width column.
	 *
	 *  @var integer $width
	 *  @access public
	 */
	$width = 70;	

	$text = trim(stripslashes($html));

	// Run our defined search-and-replace
	$text = preg_replace($search, $replace, $text);

	// Strip any other HTML tags
	$text = strip_tags($text, $allowed_tags);

	// Bring down number of empty lines to 2 max
	$text = preg_replace("/\n\s+\n/", "\n\n", $text);
	$text = preg_replace("/[\n]{3,}/", "\n\n", $text);

	// Add link list
	if ( !empty($_link_list) ) {
		$text .= "\n\nLinks:\n------\n" . $_link_list;
	}

	// Wrap the text to a readable format
	// for PHP versions >= 4.0.2. Default width is 75
	// If width is 0 or less, don't wrap the text.
	if ( $width > 0 ) {
		$text = wordwrap($text, $width);
	}

	return $text;
}

/**
 *  Helper function called by preg_replace() on link replacement.
 *
 *  Maintains an internal list of links to be displayed at the end of the
 *  text, with numeric indices to the original point in the text they
 *  appeared. Also makes an effort at identifying and handling absolute
 *  and relative links.
 *
 *  @param string $link URL of the link
 *  @param string $display Part of the text to associate number with
 *  @access private
 *  @return string
 */
function _build_link_list( $link, $display )
{
	// Variables used for building the link list
	$_link_count = 0;
	$_link_list = '';
	
	if ( substr($link, 0, 7) == 'http://' || substr($link, 0, 8) == 'https://' ||
	substr($link, 0, 7) == 'mailto:' ) {
		$_link_count++;
		$_link_list .= "[" . $_link_count . "] $link\n";
		$additional = ' [' . $_link_count . ']';
	} elseif ( substr($link, 0, 11) == 'javascript:' ) {
		// Don't count the link; ignore it
		$additional = '';
		// what about href="#anchor" ?
	} else {
		$_link_count++;
		$_link_list .= "[" . $_link_count . "] " . $url;
		if ( substr($link, 0, 1) != '/' ) {
			$_link_list .= '/';
		}
		$_link_list .= "$link\n";
		$additional = ' [' . $_link_count . ']';
	}

	return $display . $additional;
}
